/*
 * Author: aple
 *
 * Created on 2015年10月9日, 上午10:07
 */

#ifndef SIMP_log2_EXT_M_H
#define	SIMP_log2_EXT_M_H

#include "simp_log2.h"

#ifdef	__cplusplus
extern "C" {
#endif	
	/*-----------------------------------------------------------------------------------------------------*
	* 基本功能同simp_log2
	**-----------------------------------------------------------------------------------------------------*
	* 与simp_log2的区别：
	* data_size 不必对齐 2^n，但应满足为4的倍数
	* 写数据强制对齐在page_size边界，当数据尺寸不为2^N时，每页尾部会有不定长的空白。
	* 读取数据应以page_size为单位，获取blocks_per_page块数据后，舍去尾部
	* 写数据可能跨falsh页写边界，Program接口外部应有自动分页写功能
	*-----------------------------------------------------------------------------------------------------*/
	 
	void simp_log2_ext_init(const simp_log2_type * cfg);
	uint32_t simp_log2_ext_site_to_addr(const simp_log2_type * cfg, uint32_t site);
	
	void simp_log2_ext_save(const simp_log2_type * cfg);
	void simp_log2_ext_save_verify(const simp_log2_type * cfg);
	void simp_log2_ext_read(const simp_log2_type * cfg, uint32_t site, void *pdat);
	
	int32_t simp_log2_ext_site_fore(const simp_log2_type * cfg, int32_t site, int32_t fore_amount);
	int32_t simp_log2_ext_head_search(const simp_log2_type * cfg, int32_t num, int32_t *site_des);
	
	/*-----------------------------------------------------------------------------------------------------*
	 * 快速搜索，内部采用二分搜索法，从start到next-1区间
	 * mode: 0(未命中目标时返回-1)，-1(未命中目标时返回小于目标值的位置)，1(未命中目标时返回大于目标值的位置)
	 * return 返回-1代表未搜到指定结果， +数指向搜索结果位置
	 *-----------------------------------------------------------------------------------------------------*/
	int32_t simp_log2_ext_quick_search(const simp_log2_type * cfg, sig_time_type time, int8_t mode);

	/*-----------------------------------------------------------------------------------------------------*
	 * API
	 *-----------------------------------------------------------------------------------------------------*/
	#define simp_log2_ext_api_make(obj)										\
	void obj##_save(void){ simp_log2_ext_save(&obj);}						\
	void obj##_save_verify(void){ simp_log2_ext_save_verify(&obj);}			\
	void obj##_init(void ){ simp_log2_ext_init(&obj);}						\
	uint32_t obj##_site_addr(uint32_t site)									\
		{ return simp_log2_ext_site_to_addr(&obj, site);}					\
	void obj##_read(uint32_t site, void *pdat)								\
		{ simp_log2_ext_read(&obj, site, pdat);}							\
	int32_t obj##_site_fore(int32_t site, int32_t fore_amount)				\
		{ return simp_log2_ext_site_fore(&obj, site, fore_amount);}			\
	int32_t obj##_quick_search(sig_time_type time, int8_t mode)				\
		{ return simp_log2_ext_quick_search(&obj, time, mode);}				\
	int32_t obj##_head_search(int32_t num, int32_t *site_des)				\
		{ return simp_log2_ext_head_search(&obj, num, site_des);}			\
	const simp_log2_api_type  obj##_api = {									\
		obj##_save,															\
		obj##_save_verify,													\
		obj##_init,															\
		obj##_site_addr,													\
		obj##_read,															\
		obj##_site_fore,													\
		obj##_quick_search,													\
		obj##_head_search													\
	}

#define simp_log2_ext_api_ref(obj)	extern const simp_log2_api_type obj##_api
#define simp_log2_ext_api_name(obj)	&obj##_api
	
#ifdef	__cplusplus
}
#endif

#endif	/* SIMP_log2_EXT_M_H */
